package com.java3y.sso.utils;

import com.java3y.sso.annotate.InfrawInputCheck;
import com.java3y.sso.annotate.InfrawInputEqualsCheck;
import com.java3y.sso.handler.*;


import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

public class InfrawInputCheckUtils<T> {

    private static Map factory = new ConcurrentHashMap();

    static {
        factory.put("InfrawInputRequiredCheck", new InfrawInputRequiredCheckImpl());
        factory.put("InfrawInputEqualsCheck", new InfrawInputEqualsCheckImpl());
        factory.put("InfrawInputCharacterCheck", new InfrawInputCharacterCheckImpl());
        factory.put("InfrawInputListEqualsCheck", new InfrawInputListEqualsCheckImpl());

    }

    public static <T> void checkInput(T inputVo, Supplier<T> supplier) throws Exception {
        T t = null;
        if (supplier != null) {
            t = supplier.get();
        }
        Class<?> voClass = inputVo.getClass();
        InfrawInputCheck annotation = voClass.getAnnotation(InfrawInputCheck.class);
        if (annotation instanceof InfrawInputCheck) {
            Field[] declaredFields = voClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                Annotation[] annotations = declaredField.getAnnotations();
                for (Annotation filedAnnotation : annotations) {
                    InfrawInputHandler handler = (InfrawInputHandler) factory.get(filedAnnotation.annotationType().getSimpleName());
                    if (filedAnnotation instanceof InfrawInputEqualsCheck) {
                        if (t != null) {
                            Field hopeValueCheckField = t.getClass().getDeclaredField(declaredField.getName());
                            hopeValueCheckField.setAccessible(true);
                            Object hopeValue = hopeValueCheckField.get(t);
                            handler.handle(declaredField.get(inputVo), filedAnnotation,declaredField.getName(), hopeValue.toString());
                        }

                    }else {
                        handler.handle(declaredField.get(inputVo), filedAnnotation,declaredField.getName());
                    }
                }

            }

        }
    }
}
